// Une librairie Javascript pour Bajax
// Auteur : Sebastian Mosser

// Localisation du serveur Bajax
var serverUrl = "http://localhost/balloon/bajax_server.php"

// NE PAS EDITER SOUS CETTE LIGNE !! 

// Le tableau contenant les invokers :
var invokers = new Array();


// Pour echapper du contenu xml (TO DO : rendre plus 'efficace') :
function escapeXMLContent(aString) {
	var tmp = String(aString);
	tmp = tmp.replace(/&/gi,"&amp;"); // &
	tmp = tmp.replace(/</gi,"&lt;");  // <
	tmp = tmp.replace(/>/gi,"&gt;");  // >
	tmp = tmp.replace(/"/gi,"&#34;"); //"
	tmp = tmp.replace(/'/gi,"&#39;"); // '
	return tmp;	
}

// Pour créer une requete BallonXML :
function createBalloonXmlQuery(className, methodName, parameters) {
	// On echappe les caractères non xml compliant dans les paramètres :
	className  = escapeXMLContent(className);
	methodName = escapeXMLContent(methodName);
	for (p in parameters)
		parameters[p] = escapeXMLContent(parameters[p]);
		
	// On construit la requete :
	var query = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
	query += "<BalloonAjaxQuery>\n";
	query += "  <className>"  + className  + "</className>\n";
	query += "  <methodName>" + methodName + "</methodName>\n",
	query += "  <params>\n";
	for (p in parameters)
		query += "    <param>" + parameters[p] + "</param>\n";
	query += "  </params>\n"
  query += "</BalloonAjaxQuery>\n"
	return query;
}

// Fabrique d'invokeurs distant :
function httpFactory() {
	var invoker = false;
	// Creation de l'invoker :
	if (window.XMLHttpRequest) 			   	 // Firefox 
		invoker = new XMLHttpRequest(); 
	else if(window.ActiveXObject) {      // Internet Explorer 
		invoker = new ActiveXObject("Microsoft.XMLHTTP");
	}
	else {
		var fail = "Echec d'instanciation de l'invocateur distant :'( \n";
		fail += "Votre navigateur ne semble pas supporter l'invocation de méthodes distantes ...\n";
		fail += "Veuillez utiliser quelque chose d'un peu plus standart, comme Firefox par exemple ^_^ !\n";
		alert(fail); 
		invoker = -1; 
		exit(); // On dégage :p
	}
	return invoker;
}

// Invocation distante Bajax :
function invoke(id,className, methodName, parameters, callBackFunction) {
	// On remet a jour l'invoker : désactivation puis instanciation
	invokers[id] = false;
	invokers[id] = httpFactory();
	// IE n'autorise pas les lignes suivantes ...
	//if (invokers[id] == -1)
	//	return;

	// Creation de la requete :
	var xmlQuery = createBalloonXmlQuery(className, methodName, parameters);	
	// On instancie la fonction de callback :
	invokers[id].onreadystatechange = function() {
		switch(invokers[id].readyState) {			
			case 0:
			  bajaxStatus("Invocateur distant non initialisé");
				break;
			case 1:
				bajaxStatus("Début du transfert des données");
				break;
			case 2: 
				bajaxStatus("Données transférées");
				break;
			case 3: 
			  bajaxStatus("Les données sont disponible partiellement");
				break;
			case 4:
				bajaxStatus("Les données ont été recues !");
				if (invokers[id].status == 200) {
	      	callBackFunction(invokers[id].responseText);
	      	bajaxHide();
	      }
				else {
		      var msg = "Erreur d'invocation distante :";
		      msg += " Erreur HTTP : " + invokers[id].status;
	   	   	callBackFunction(msg);
	   	   }
	   	  break;
		}
	} 	
	
	// Ouverture de la connexion au serveur Bajax
	invokers[id].open("POST",serverUrl, true);	
	// On met en place le bon header pour l'envoi de données :
	invokers[id].setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	invokers[id].setRequestHeader("Charset", "utf-8");
	// On prépare l'envoie de la requete XML, en échappant les caractères URL :
	var query = "request="+escape(xmlQuery);
	// On envoie !	
	invokers[id].send(query);
}

// Effectue une information sur l'etat des requetes Bajax
function bajaxStatus(text) {
  var bajaxElem = document.getElementById("bajaxInfo");
  bajaxElem.style.visibility = "visible";
  bajaxElem.innerHTML = "&nbsp;&nbsp;" + text + "&nbsp;&nbsp;";
}

// Desactive la barre d'etat bajax :
function bajaxHide() {
  var bajaxElem = document.getElementById("bajaxInfo");
  bajaxElem.style.visibility = "hidden";
}